class ClientsController < ApplicationController
  before_filter :authenticate_client , :except => [ :create ]


  def create
    begin
      @client     = Client.create client_params
      secret      = @client.secret
      room_secret = @client.room.secret unless @client.new_record?
    rescue ActiveRecord::RecordNotUnique
      client      = Client.find_by_name URI.escape client_params[:name]
      secret      = DUPLICATE_CLIENT_SECRET
      room_secret = client.room.secret
    end

    (fail 420) and return if (@client.nil? || @client.new_record?) &&
                       secret != DUPLICATE_CLIENT_SECRET

    render :json => { :secret => secret , :room_secret => room_secret }
  end

  def ping ; render :json => { :pong => 'ok' } ; end ;

  def rooms
    rooms = Room.where "id != ? AND is_public = ?" , @client.room.id , true

    (fail 420) and return if rooms.nil?

    rooms_resp = rooms.map do | room |
      { :secret  => room.secret      ,
        :clients => room.clients_csv }
    end

    render :json => { :rooms => rooms_resp }
  end

  def bridge
    bridge_room = Room.find_by_secret bridge_params[:room_secret]

    if bridge_room.present? && bridge_room != @client.room
      @client.room.destroy if @client.room.clients.count == 1
      @client.room = bridge_room
      @client.save
    end

    (fail 420) and return if bridge_room.nil?

    render :json => { :room_secret => @client.room.secret      ,
                      :clients     => @client.room.clients_csv }
  end

  def message
    message = @client.room.messages.create message_params

    (fail 420) and return if message.nil? || message.new_record?

    @client.room.messages.first.delete

    render :json => { :message => 'ok' }
  end

  def messages
    begin
      last_id  = messages_params[:last_id]
      messages = (@client.room.messages.where "id > ?" , last_id) unless last_id.blank?
    rescue ArgumentError
    end

    (fail 420) and return if messages.nil?

    render :json => { :messages => messages }
  end

  def fail status ; render :text => 'NFG' , :status => status ; end ;


private

  def authenticate_client
    begin
      params = auth_params
      name   = params[:name  ] || ''
      secret = params[:secret]
      client = (Client.find_by_name name           ) ||
               (Client.find_by_name URI.escape name)
    rescue ActionController::ParameterMissing
    end

    @client = client if client.present? && client.secret == secret

    (fail 401) and return unless @client.present?

    @client.touch
  end

  def auth_params
    begin
      { :name   => (params.require :name  )                  ,
        :secret => (params.require :client).require(:secret) }
    rescue ActionController::ParameterMissing
      { :name => '' , :secret => '' }
    end
  end

  def client_params
    begin
      client = params.require :client
      { :name  => (client.require :name ) ,
        :nicks => (client.require :nicks) ,
        :type  => (client.require :type ) }
    rescue ActionController::ParameterMissing
      { :name => '' , :nicks => '' , :type => '' }
    end
  end

  def bridge_params
    begin
      { :room_secret => (params.require :room_secret) }
    rescue ActionController::ParameterMissing
      { :room_secret => '' }
    end
  end

  def message_params
    begin
      message = params.require :message
      { :nick => (message.require :nick) ,
        :text => (message.require :text) }
    rescue ActionController::ParameterMissing
      { :nick => '' , :text => '' }
    end
  end

  def messages_params
    begin
      { :last_id => (params.require :last_id) }
    rescue ActionController::ParameterMissing
      { :last_id => '' }
    end
  end
end
